/*
 * Copyright (c) 2010, German Buela
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * The name of German Buela may not be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY GERMAN BUELA "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL GERMAN BUELA BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.gbuela.swt

import org.eclipse.swt.widgets._
import org.eclipse.swt.events._
import org.eclipse.swt.graphics._
import java.io.FileInputStream
import java.io.InputStream

import org.eclipse.swt._

object SwtImage {
   def inputStream(fileName: String) : InputStream = {
     val is: InputStream = if(fileName startsWith ".")       
         this.getClass.getResourceAsStream(fileName.substring(1))
     else
       new FileInputStream(fileName)

     is
   }
}

class SwtImage(container:Composite, fileName:String, hoverFileName: Option[String], 
               clickFileName: Option[String], scale:Option[(Int,Int)], pos:Option[(Int,Int)], 
               tooltipText: Option[String], clickHandler: Option[() => Unit]) {
   implicit def evt2disposeListener(evt: => Unit):DisposeListener = new DisposeListener() { def widgetDisposed(e:DisposeEvent):Unit = evt }
   implicit def evt2mouseListener(evt: () => Unit):MouseListener = new MouseListener() {
     def mouseDoubleClick(e:MouseEvent) = ()
     def mouseDown(e:MouseEvent) = ()
     def mouseUp(e:MouseEvent) = if(within(e.x,e.y,imgLbl.getBounds)) { evt() }
   }

   val imgLbl = new Label(container, SWT.NONE)
   if(tooltipText.isDefined) imgLbl.setToolTipText(tooltipText.get)
   var img:Image = null
   var altImg: Image = null
   var clickImg: Image = null

   try {
     val oriData = new ImageData(SwtImage.inputStream(fileName))
     val data = scale match {
       case None => oriData
       case Some((w,h)) => oriData.scaledTo(w,h)
     }
     img = new Image(container.getDisplay, data)
     
     if (hoverFileName.isDefined)
     {
		 val altOriData = new ImageData(SwtImage.inputStream(hoverFileName.get ))
		     val altData = scale match {
	       case None => altOriData
	       case Some((w,h)) => altOriData.scaledTo(w,h)
	     }
	 	 altImg = new Image(container.getDisplay, altData)

		 imgLbl addMouseTrackListener new MouseTrackListener() {
		     def mouseEnter(e: MouseEvent) =  imgLbl.setImage(altImg)
		     def mouseExit(e: MouseEvent) = imgLbl.setImage(img)
		     def mouseHover(e: MouseEvent) = ()
		 }
     }
   }
   if (clickFileName.isDefined)
   {
		 val clkOriData = new ImageData(SwtImage.inputStream(clickFileName.get ))
		     val clkData = scale match {
	       case None => clkOriData
	       case Some((w,h)) => clkOriData.scaledTo(w,h)
	     }
	 	 clickImg = new Image(container.getDisplay, clkData)

        imgLbl addMouseListener new MouseListener() {
	     def mouseDoubleClick(e:MouseEvent) = ()
	     def mouseDown(e:MouseEvent) = imgLbl.setImage(clickImg)
	     def mouseUp(e:MouseEvent) = imgLbl.setImage(img)
     }
   }   
   
  imgLbl.setImage(img)
  container addDisposeListener { if(img != null) img.dispose else () }
  container addDisposeListener { if(altImg != null) altImg.dispose else () }
  container addDisposeListener { if(clickImg  != null) clickImg.dispose else () }

   if(clickHandler.isDefined)
   {
     imgLbl addMouseListener clickHandler.get
	 imgLbl.setCursor(new Cursor(container.getDisplay, SWT.CURSOR_HAND))
   }
   
   private def within(x:Int,y:Int,r:Rectangle):Boolean = return x >= 0 && y >= 0 && x <= r.width && y <= r.height
}
